package com.xjy.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjy.common.core.mybatisplus.core.ServicePlusImpl;
import com.xjy.common.core.page.PagePlus;
import com.xjy.common.core.page.TableDataInfo;
import com.xjy.common.exception.CustomException;
import com.xjy.common.exception.UtilException;
import com.xjy.common.utils.PageUtils;
import com.xjy.system.domain.SysCreditAdvance;
import com.xjy.system.domain.SysDeposit;
import com.xjy.system.domain.SysLoan;
import com.xjy.system.domain.bo.*;
import com.xjy.system.domain.vo.SysCreditAdvanceVo;
import com.xjy.system.domain.vo.SysLoanVo;
import com.xjy.system.domain.vo.SysLoanVo;
import com.xjy.system.mapper.SysLoanMapper;
import com.xjy.system.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 个人借款信息Service业务层处理
 *
 * @author xjy
 * @date 2022-02-10
 */
@Service
public class SysLoanServiceImpl extends ServicePlusImpl<SysLoanMapper, SysLoan> implements ISysLoanService {
	@Autowired
	private ISysProjService iSysProjService;

	@Autowired
	private ISysFundaccountdetailService iSysFundaccountdetailService;
	@Autowired
	private ISysCheckaccountService iSysCheckaccountService;

	@Override
	public SysLoanVo queryById(Long id) {
		return getVoById(id, SysLoanVo.class);
	}
	@Autowired
	private ISysImageMngService iSysImageMngService;


	@Override
	public TableDataInfo<SysLoanVo> queryPageList(SysLoanQueryBo bo) {
		List<SysLoanVo> list = baseMapper.queryList(bo);
		return PageUtils.getPageInfo(list);
	}

	@Override
	public List<SysLoanVo> queryList(SysLoanQueryBo bo) {
		return listVo(buildQueryWrapper(bo), SysLoanVo.class);
	}

	@Override
	public List<SysLoanVo> querySelectList() {
		return baseMapper.querySelectList();

	}


	private LambdaQueryWrapper<SysLoan> buildQueryWrapper(SysLoanQueryBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<SysLoan> lqw = Wrappers.lambdaQuery();
		lqw.eq(bo.getProjId() != null, SysLoan::getProjId, bo.getProjId());
		lqw.like(StrUtil.isNotBlank(bo.getContractName()), SysLoan::getContractName, bo.getContractName());
		lqw.eq(bo.getContractId() != null, SysLoan::getContractId, bo.getContractId());
		lqw.eq(bo.getResultContractId() != null, SysLoan::getResultContractId, bo.getResultContractId());
		lqw.eq(bo.getBudgetId() != null, SysLoan::getBudgetId, bo.getBudgetId());
		lqw.eq(StrUtil.isNotBlank(bo.getResultContractNo()), SysLoan::getResultContractNo, bo.getResultContractNo());
		lqw.in(null != bo.getResultContractNoList() &&  bo.getResultContractNoList().size() >0, SysLoan::getResultContractNo, bo.getResultContractNoList());
		lqw.eq(StrUtil.isNotBlank(bo.getResultContractNoBack()), SysLoan::getResultContractNoBack, bo.getResultContractNoBack());
		lqw.eq(bo.getLoanType() != null, SysLoan::getLoanType, bo.getLoanType());
		lqw.eq(StrUtil.isNotBlank(bo.getBorrower()), SysLoan::getBorrower, bo.getBorrower());
		lqw.eq(StrUtil.isNotBlank(bo.getResultContractNoCharge()), SysLoan::getResultContractNoCharge, bo.getResultContractNoCharge());
		lqw.eq(bo.getBorrowerId() != null, SysLoan::getBorrowerId, bo.getBorrowerId());
		lqw.eq(StrUtil.isNotBlank(bo.getAbstracted()), SysLoan::getAbstracted, bo.getAbstracted());
		lqw.eq(bo.getAmount() != null, SysLoan::getAmount, bo.getAmount());
		lqw.eq(bo.getBalance() != null, SysLoan::getBalance, bo.getBalance());
		lqw.eq(StrUtil.isNotBlank(bo.getColBank()), SysLoan::getColBank, bo.getColBank());
		lqw.eq(bo.getWriteoffStatus() != null, SysLoan::getWriteoffStatus, bo.getWriteoffStatus());
		lqw.eq(StrUtil.isNotBlank(bo.getHandler()), SysLoan::getHandler, bo.getHandler());
		lqw.eq(StrUtil.isNotBlank(bo.getColBankNo()), SysLoan::getColBankNo, bo.getColBankNo());
		lqw.eq(bo.getHandlerId() != null, SysLoan::getHandlerId, bo.getHandlerId());
		lqw.eq(bo.getPayType() != null, SysLoan::getPayType, bo.getPayType());
		lqw.eq(bo.getPayAccountId() != null, SysLoan::getPayAccountId, bo.getPayAccountId());
		lqw.eq(StrUtil.isNotBlank(bo.getPayAccountBank()), SysLoan::getPayAccountBank, bo.getPayAccountBank());
		lqw.eq(StrUtil.isNotBlank(bo.getPayAccountNo()), SysLoan::getPayAccountNo, bo.getPayAccountNo());
		lqw.eq(bo.getAuditStatus() != null, SysLoan::getAuditStatus, bo.getAuditStatus());
		lqw.in(null != bo.getIdList() && bo.getIdList().size() > 0, SysLoan::getId,bo.getIdList());
		return lqw;
	}

	@Override
	public Boolean insertByAddBo(SysLoanAddBo bo) {
		SysLoan add = BeanUtil.toBean(bo, SysLoan.class);
		return save(add);
	}

	private void writeoffStatusCheck(SysLoan sysLoan) {
		if (sysLoan.getLoanType() == 0) {
			//支付
			return;
		}
		BigDecimal sumAmt = getBaseMapper().sumAmount(sysLoan.getResultContractNo());
		SysLoan loan = getBaseMapper().selectByResultContractNo(sysLoan.getResultContractNo());
		double res = loan.getAmount().subtract(sumAmt).subtract(sysLoan.getAmount()).doubleValue();
		if (res == 0) {
			loan.setWriteoffStatus(1);
			updateByBo(loan);
		} else if (res < 0) {
			throw new CustomException("退款金额超付");
		}

	}

	public Boolean updateByBo(SysLoan update) {
		return updateById(update);
	}

	@Override
	public Boolean updateByEditBo(SysLoanEditBo bo) {
		SysLoan update = BeanUtil.toBean(bo, SysLoan.class);
		return updateById(update);
	}

	@Override
	@Transactional
	public synchronized Boolean auditByEditBo(BaseAuditBo req) {
		boolean rsp = false;
		List<Long> idList = req.getIdList();
		if(null == idList || idList.size() == 0){
			throw new CustomException("需审核的数据不能为空！");
		}
		SysLoanQueryBo sysLoanQueryBo = new SysLoanQueryBo();
		sysLoanQueryBo.setIdList(idList);
		sysLoanQueryBo.setAuditStatus(false);
		List<SysLoanVo>  sysLoanVoList = this.queryList(sysLoanQueryBo);
		if(null == sysLoanVoList || sysLoanVoList.size() == 0){
			throw new CustomException("勾选的数据审核状态已审批，无需重新审批！");
		}
		for(SysLoanVo sysLoanVo:sysLoanVoList){
			// TODO 结账效验
			iSysCheckaccountService.check(sysLoanVo.getProjId(),sysLoanVo.getCreateTime());
			SysLoan updateOne = new SysLoan();
			updateOne.setId(sysLoanVo.getId());

			String resultContractNo = sysLoanVo.getResultContractNo();
			Integer loanType = sysLoanVo.getLoanType();
			BigDecimal amount = sysLoanVo.getAmount();
			if(amount.compareTo(new BigDecimal(0)) <= 0){
				throw new UtilException("发生金额必须大于0！");
			}
			BigDecimal advanceBalance = null;
			//个人借款类别：0：支付借款，1：归还借款
			if(loanType.equals(0)){
				advanceBalance = amount;
			}

			if(loanType.equals(1)){
				SysLoanQueryBo sysLoanQueryBoReq = new SysLoanQueryBo();
				sysLoanQueryBoReq.setResultContractNo(resultContractNo);
				sysLoanQueryBoReq.setLoanType(0);
				sysLoanQueryBoReq.setAuditStatus(true);
				List<SysLoanVo> list = this.queryList(sysLoanQueryBoReq);
				if(null == list || list.size() == 0){
					throw new UtilException("借款归还,未查询到对应支付借款单！");
				}
				SysLoanVo payInfo = list.get(0);
				if(payInfo.getWriteoffStatus().equals(1)){
					throw new UtilException("借款归还,借款单单已是冲销状态！");

				}
				SysLoan updatePay = new SysLoan();
				BigDecimal advanceBalanceNow = payInfo.getBalance();
				if(advanceBalanceNow.compareTo(amount) == -1){
					throw new UtilException("归还金额不能大于余额！");
				}

				//计算余额
				BigDecimal advanceBalanceNew = advanceBalanceNow.subtract(amount);
				if(advanceBalanceNew.compareTo(new BigDecimal(0)) == 0){
					//已冲销
					updatePay.setWriteoffStatus(1);
				}
				updatePay.setId(payInfo.getId());
				updatePay.setBalance(advanceBalanceNew);
				baseMapper.updateById(updatePay);

			}
			updateOne.setBalance(advanceBalance);
			boolean changeFundaccount = this.changeFundaccount(sysLoanVo);
			if(!changeFundaccount){
				throw new CustomException("更新资金流水失败！");
			}
			if(sysLoanVo.getLoanType() == 0){
				this.uploadImage(sysLoanVo);

			}
			updateOne.setAuditStatus(true);
			rsp = baseMapper.updateById(updateOne) >0;

		}

		return rsp;
	}

	private synchronized Boolean changeFundaccount(SysLoanVo bo){
		Integer loanType = bo.getLoanType();
		//借款冲销报错2
		if (loanType.equals(2)) {
			throw new CustomException("借款冲销数据，无须手动审核！");

		}
		SysFundaccountdetailAddBo addBo = new SysFundaccountdetailAddBo();

		//1：归还借款+
		if (loanType.equals(1)) {
			addBo.setCategory(0L);
		}
		//支付借款0-
		if (loanType.equals(0)) {
			addBo.setCategory(1L);


		}

		addBo.setProjId(bo.getProjId());
		addBo.setProjName(bo.getProjName());
		addBo.setSubjectId(bo.getBudgetId());
		addBo.setSubjectName(bo.getBudgetName());
		addBo.setContractId(bo.getContractId());
		addBo.setContractName(bo.getContractName());
		addBo.setSettleProj(bo.getResultContractId());
		addBo.setSettleProjName(bo.getResultContractName());

		addBo.setAccId(bo.getPayAccountId());
		addBo.setAccountName(bo.getPayAccountName());
		addBo.setAccountBank(bo.getPayAccountBank());
		addBo.setAccountNo(bo.getPayAccountNo());
		//0：支付借款-，1：归还借款+
		if(loanType.equals(0)){
			addBo.setTransactionId(bo.getResultContractNo());
			addBo.setTransactionCategory(3L);
		}else {

			addBo.setTransactionId(bo.getResultContractNoBack());
			addBo.setTransactionCategory(3L);
		}
		addBo.setSenderId(bo.getPayAccountId());
		addBo.setSender(bo.getPayAccountName());
		addBo.setReceiveId(bo.getBorrowerId());
		addBo.setReceive(bo.getBorrower());
		addBo.setManagerId(bo.getHandlerId());
		addBo.setManager(bo.getHandler());
		addBo.setTransactionType(bo.getPayType());

		addBo.setTransactionDate(bo.getCreateTime());
		addBo.setAmount(bo.getAmount());
		addBo.setRemarks(bo.getRemark());
		return iSysFundaccountdetailService.insertByAddBo(addBo);
	}
	private boolean uploadImage(SysLoanVo bo){
		boolean rsp = false;
		if(StringUtils.isNotBlank(bo.getImage()) && !"[]".equals(bo.getImage())){
			SysImageMngAddBo sysImageMngAddBo = new SysImageMngAddBo();
			sysImageMngAddBo.setAuditStatus(true);
			sysImageMngAddBo.setProjId(bo.getProjId());
			sysImageMngAddBo.setImage(bo.getImage());
			sysImageMngAddBo.setType(3+"");
			sysImageMngAddBo.setOperatorId(bo.getHandlerId());
			sysImageMngAddBo.setOperator(bo.getHandler());
			sysImageMngAddBo.setOutNo(bo.getResultContractNo());

			rsp = iSysImageMngService.insertByAddBo(sysImageMngAddBo);
		}

		return rsp;
	}
	/**
	 * 保存前的数据校验
	 *
	 * @param entity 实体类数据
	 */
	private void validEntityBeforeSave(SysLoan entity) {
		//TODO 做一些数据校验,如唯一约束
	}

	@Override
	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
		if (isValid) {
			//TODO 做一些业务上的校验,判断是否需要校验
		}
		return removeByIds(ids);
	}
}
